<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>怎么缓存Vue组件以及怎么更新</title>
  </head>
  <body>
    <h2>怎么缓存Vue组件以及怎么更新</h2>
    <p>
      开发中缓存组件使用keep-alive组件，keep-alive是vue内置组件，keep-alive包裹动态组件component时，缓存不活动的组件实例，而不是销毁他们，(使用空间换时间)这样在组建切换过程中将状态保留在内存中，防止重复渲染DOM
    </p>

    <keep-alive>
      <component :is="show"></component>
    </keep-alive>

    <p>结合属性include和exclude可以明确指定缓存哪些组件或排除缓存指定组件。vue3中结合vue-router时变化较大，之前是`keep-alive`包裹`router-view`，现在需要反过来用`router-view`包裹`keep-alive`</p>

    <router-view v-slot="{ Component }">
      <keep-alive>
        <component :is="show"></component>
      </keep-alive>
    </router-view>

    <h2>缓存后如果要获取数据，解决方案：</h2>
    <p>beforeRouteEnter：在有vue-router的项目，每次进入路由的时候，都会执行`beforeRouteEnter`</p>
    beforeRouteEnter(to, from, next) {
      next(vm => {
        console.log(vm)
        // 每次进入路由都会执行
        vm.getData() //  获取数据
      })
    }

    <p>actived：在`keep-alive`缓存组件被激活的时候，都会执行`actived`钩子</p>
    activated() {
      this.getData() //  获取数据
    }

    <h2>keep-alive原理，它是一个通用组件，它内部定义了一个map，缓存创建过的组件实例，它返回的渲染函数内部会查找内嵌的component组件对应的vnode，如果该组价在map中存在就直接返回它，由于component的is属性是个响应式数据，一次只要他变化，keep-alive的render函数就会重新执行。就会重新进行path流程</h2>
    选项参数：include、exclude、max
    <p>存到map中的其实是一个虚拟dom，虚拟dom中保存了对应的真实dom</p>
    map => {
      组件1：vnode,
      组件2：vnode，
      组件N：vnode
    }
  </body>
</html>
